package container

import (
	"bytes"
	"fmt"
)

type GBMap struct {
	mapValue map[interface{}]interface{}
}

// 创建新空对象
func GBNewMap() * GBMap {
	return &GBMap {
		mapValue:make(map[interface{}]interface{}, 0),
	}
}

// 打印
func (obj * GBMap) String() string {
	return fmt.Sprintf("%v", obj.mapValue)
}

// 将 key 拼接成字符串
func (obj * GBMap) JoinKeys(sep string) string {
	var i = 0
	var buff bytes.Buffer
	for k := range obj.mapValue {
		buff.WriteString(fmt.Sprint(k))
		if i < len(obj.mapValue) - 1 {
			buff.WriteString(sep)
		}
		i ++
	}
	return buff.String()
}

// 克隆新对象
func (obj * GBMap) Clone() * GBMap {
	result := &GBMap {
		mapValue:make(map[interface{}]interface{}, 0),
	}
	for k, v := range obj.mapValue {
		result.mapValue[k] = v
	}
	return result
}

// 遍历
func (obj * GBMap) ForEach(fcb func(interface{}, interface{})) {
	for k, v := range obj.mapValue {
		fcb(k, v)
	}
}

// 是否空
func (obj * GBMap) Empty() bool {
	return len(obj.mapValue) == 0
}

// 总数
func (obj * GBMap) Count() int {
	return len(obj.mapValue)
}

// 取值
func (obj * GBMap) Get(key interface{}) (val interface{}, ok bool) {
	val, ok = obj.mapValue[key]
	return
}

// 取值 如果不存在 返回默认值
func (obj * GBMap) GetOrDefault(key interface{}, valNx interface{}) interface{} {
	if val, ok := obj.mapValue[key]; ok {
		return val
	}
	return valNx
}

// 取值 如果不存在 插入并返回默认值
func (obj * GBMap) GetOrInsert(key interface{}, valNx interface{}) interface{} {
	if val, ok := obj.mapValue[key]; ok {
		return val
	} else {
		obj.mapValue[key] = valNx
	}
	return valNx
}

// 取值 如果不存在 分配值插入并返回
func (obj * GBMap) GetOrInsertFunc(key interface{}, valNxAlloc func () interface{}) interface{} {
	val, ok := obj.mapValue[key]
	if ok {
		return val
	}
	val = valNxAlloc()
	obj.mapValue[key] = val
	return val
}

// 是否包含
func (obj * GBMap) Contains(key interface{}) bool {
	_, ok := obj.mapValue[key]
	return ok
}

// 是否包含任意
func (obj * GBMap) ContainsAny(keys ...interface{}) bool {
	for _, k := range keys {
		if _, ok := obj.mapValue[k]; ok {
			return true
		}
	}
	return false
}

// 是否包含所有
func (obj * GBMap) ContainsAll(keys ...interface{}) bool {
	for _, k := range keys {
		if _, ok := obj.mapValue[k]; ok {
			continue
		}
		return false
	}
	return true
}

// 添加
func (obj * GBMap) Put(key, val interface{}) {
	obj.mapValue[key] = val
}

// 删除
func (obj * GBMap) Remove(keys ...interface{}) {
	for _, k := range keys {
		delete(obj.mapValue, k)
	}
}

// 删除按处理
func (obj * GBMap) RemoveIf(fn func (val interface{}) bool, keys ...interface{}) int {
	var count = 0
	for _, k := range keys {
		if val, ok := obj.mapValue[k]; ok {
			if fn(val) {
				delete(obj.mapValue, k)
				count ++
			}
		}
	}
	return count
}

// 对比交换
func (obj * GBMap) CompareAndSet(key, expect, update interface{}) bool {
	val, ok := obj.mapValue[key]
	// 检查是否已存在
	if ok {
		// 存在的值，比对是否相同
		if val == expect {
			obj.mapValue[key] = update
			return true
		}
	} else {
		// 不存在的值，比对是否 nil
		if nil == expect {
			obj.mapValue[key] = update
			return true
		}
	}
	// 比对不一致
	return false
}

// 并集
func (obj * GBMap) Union(maps ... * GBMap) * GBMap {
	result := obj.Clone()
	for _, m := range maps {
		for k, v := range m.mapValue {
			result.mapValue[k] = v
		}
	}
	return result
}

// 差集
func (obj * GBMap) Difference(maps ... * GBMap) * GBMap {
	result := obj.Clone()
	for _, m := range maps {
		for k := range m.mapValue {
			if _, ok := obj.mapValue[k]; ok {
				delete(result.mapValue, k)
			}
		}
	}
	return result
}

// 交集
func (obj * GBMap) Intersect(maps ... * GBMap) * GBMap {
	result := obj.Clone()
	for _, m := range maps {
		for k := range obj.mapValue {
			if _, ok := m.mapValue[k]; ok {
				continue
			} else {
				delete(result.mapValue, k)
			}
		}
	}
	return result
}

// 补集
func (obj * GBMap) Complement(full * GBMap) * GBMap {
	result := GBNewMap()
	for k, v := range full.mapValue {
		if _, ok := obj.mapValue[k]; ok {
			continue
		} else {
			result.Put(k, v)
		}
	}
	return result
}
